<template>
	<view class="yb-flex" :id="customIdSync" :class="customClassSync" :style="customStyleSync">
		<view class="yb-trans" ref="trans" :animation="animationData"
		:style="transStyle">
			<view :style="{
				width: pixelWidth,
				height: pixelHeight
			}">
				<slot></slot>
			</view>
		</view>
	</view>
</template>

<script>
	import Util from '../../js_sdk/util.js'
	import ComponentMixin from '../../js_sdk/componentMixin.js'
	export default {
		mixins: [ComponentMixin],
		props: {
			visible: {
				type: Boolean,
				default: true
			},
			name: {
				type: String,
				default: 'fade'
			},
			duration: {
				type: [Number, String],
				default: 300
			},
			delay: {
				type: [Number, String],
				default: 0
			},
			timing: {
				type: String,
				default: 'linear'
			},
			width: {
				type: [Number, String],
				default: 'auto'
			},
			height: {
				type: [Number, String],
				default: 'auto'
			}
		},
		computed: {
			transStyle () {
				return this.getHideStyle()
			},
			pixelWidth () {
				return Util.pixelunit(this.width)
			},
			pixelHeight () {
				return Util.pixelunit(this.height)
			}
		},
		data () {
			return {
				animationData: []
			}
		},
		mounted() {
			if ( this.visible ) {
				setTimeout(() => {
					this.start(true)
				}, 100)
			}
		},
		methods: {
			start (bol) {
				let styles = bol ? this.getShowStyle() : this.getHideStyle()
				// #ifdef APP-NVUE
				const animation = weex.requireModule('animation');
				animation.transition(this.$refs.trans, {
				    styles: styles,
				    duration: this.duration, //ms
				    timingFunction: this.timing,
				    needLayout:true,
				    delay: this.delay //ms
				}, () => {
					this.$emit('update:visible', bol)
					this.$emit(bol ? 'show' : 'hide')
				})
				// #endif
				// #ifndef APP-NVUE
				const animation = uni.createAnimation({
					timingFunction: this.timing,
					delay: this.delay
				})
				let stylesKey = []
				if ( this.name.indexOf('slide') > -1 || this.name.indexOf('zoom') > -1 ) {
					let newStyles = {}
					Object.keys(styles).forEach(key => {
						if ( key == 'transform' ) {
							let value = styles[key].match(/\(([\s\S]*?)\)/)
							newStyles[styles[key].replace(value[0], '')] = value[1].indexOf('rpx') > -1 ? uni.upx2px(value[1].replace('rpx', '')) : value[1]
						} else {
							newStyles[key] = styles[key]
						}
					})
					stylesKey = Object.keys(newStyles)
					styles = newStyles
				} else {
					stylesKey = Object.keys(styles)
				}
				if ( stylesKey.length == 1 ) {
					animation[stylesKey[0]](styles[stylesKey[0]]).step({duration: this.duration})
				} else {
					animation[stylesKey[0]](styles[stylesKey[0]])[stylesKey[1]](styles[stylesKey[1]]).step({duration: this.duration})
				}
				this.animationData = animation.export()
				this.$nextTick(() => {
					this.animationData = []
					if ( this.timer ) {
						clearTimeout(this.timer)
						this.timer = null
					}
					this.timer = setTimeout(() => {
						this.$emit('update:visible', bol)
						this.$emit(bol ? 'show' : 'hide')
						clearTimeout(this.timer)
						this.timer = null
					}, parseInt(this.delay) + parseInt(this.duration))
				})
				// #endif
			},
			getShowStyle () {
				return this.name == 'height' ? {
					height: this.pixelHeight
				} : this.name == 'width' ? {
					width: this.pixelWidth
				} : this.name == 'slide-right' ? {
					transform: 'translateX(0)'
				} : this.name == 'slide-left' ? {
					transform: 'translateX(0)'
				} : this.name == 'slide-top' ? {
					transform: 'translateY(0)'
				} : this.name == 'slide-bottom' ? {
					transform: 'translateY(0)'
				} : this.name == 'zoom' ? {
					transform: 'scale(1)'
				} : this.name == 'height-fade' ? {
					height: this.pixelHeight,
					opacity: 1
				} : this.name == 'width-fade' ? {
					width: this.pixelWidth,
					opacity: 1
				} : this.name == 'slide-right-fade' ? {
					transform: 'translateX(0)',
					opacity: 1
				} : this.name == 'slide-left-fade' ? {
					transform: 'translateX(0)',
					opacity: 1
				} : this.name == 'slide-top-fade' ? {
					transform: 'translateY(0)',
					opacity: 1
				} : this.name == 'slide-bottom-fade' ? {
					transform: 'translateY(0)',
					opacity: 1
				} : this.name == 'zoom-fade' ? {
					transform: 'scale(1)',
					opacity: 1
				} : {
					opacity: 1
				}
			},
			getHideStyle () {
				return this.name == 'height' ? {
					height: 0
				} : this.name == 'width' ? {
					width: 0
				} : this.name == 'slide-right' ? {
					transform: 'translateX(' + this.pixelWidth + ')'
				} : this.name == 'slide-left' ? {
					transform: 'translateX(-' + this.pixelWidth + ')'
				} : this.name == 'slide-top' ? {
					transform: 'translateY(-' + this.pixelHeight + ')'
				} : this.name == 'slide-bottom' ? {
					transform: 'translateY(' + this.pixelHeight + ')'
				} : this.name == 'zoom' ? {
					transform: 'scale(0)'
				} : this.name == 'height-fade' ? {
					height: 0,
					opacity: 0
				} : this.name == 'width-fade' ? {
					width: 0,
					opacity: 0
				} : this.name == 'slide-right-fade' ? {
					transform: 'translateX(' + this.pixelWidth + ')',
					opacity: 0
				} : this.name == 'slide-left-fade' ? {
					transform: 'translateX(-' + this.pixelWidth + ')',
					opacity: 0
				} : this.name == 'slide-top-fade' ? {
					transform: 'translateY(-' + this.pixelHeight + ')',
					opacity: 0
				} : this.name == 'slide-bottom-fade' ? {
					transform: 'translateY(' + this.pixelHeight + ')',
					opacity: 0
				} : this.name == 'zoom-fade' ? {
					transform: 'scale(0)',
					opacity: 0
				} : {
					opacity: 0
				}
			}
		},
		beforeDestroy() {
			this.animationData = []
		},
		watch: {
			visible ( newVal ) {
				setTimeout(() => {
					this.start(newVal)
				}, 20)
			}
		}
	}
</script>

<style scoped>
	.yb-trans {
		/* #ifndef APP-NVUE */
		display: flex;
		flex-direction: column;
		box-sizing: border-box;
		overflow: hidden;
		/* #endif */
	}
</style>